package seedpod.kb2db;
/**
 * Copyright 2009 University of  Washington
 * This code is released under the GPL version 3 - with a copy of the license included
 * @author Maya Hao Li
 *
 */
/**
 * <p>Title: KnowldgeBase to Database</p>
 * <p>Description: Writes the RDB Schema in a generic XML format</p>
 * <p>Copyright: Copyright (c) 2002</p>
 * <p>Company: University of Washington BHI</p>
 * @author Hao Li
 * @version 2.0
 */

import java.io.IOException;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.Vector;

import seedpod.model.rdb.Attribute;
import seedpod.model.rdb.Rdb;
import seedpod.model.rdb.Relation;
import seedpod.model.rdb.SimpleForeignKey;
import seedpod.model.rdb.View;
import seedpod.util.XMLWriter;

public class RdbXmlWriter
{
    private Rdb _rdb;
    private XMLWriter _xmlStream;

    public RdbXmlWriter(Rdb rdb) {
        _rdb = rdb;
        _xmlStream = new XMLWriter( "RDB" );
    }

    /**
     * writes out a generic XML document for the RDB
     * 
     * @param out
     * @return
     * @throws KBtoDB.XMLWriter.XMLException
     */
    public void serializeXML() throws XMLWriter.XMLException, IOException {
        Iterator<Relation> relItr = _rdb.getRelations().iterator();
        Iterator<SimpleForeignKey> keyItr = _rdb.getForeignKeys().iterator();
        Iterator<View> viewItr = _rdb.getViews().iterator();
        // relations
        XMLWriter swriter = _xmlStream.addElement( "schema" );
        swriter.addElement( "schema_name", _rdb.getName() );
        Relation rel;
        while (relItr.hasNext()) {
            rel = (Relation)relItr.next();
            serializeRelation( rel, swriter );
        }

        // foreign keys
        SimpleForeignKey fk;
        while (keyItr.hasNext()) {
            fk = (SimpleForeignKey)(keyItr.next());
            // fk.serializeXML( _xmlStream );
            serializeForeignKey( fk, swriter );
        }

        View view;
        while (viewItr.hasNext()) {
            view = (View)(viewItr.next());
            view.serializeXML( _xmlStream );
        }

    }

    protected void serializeForeignKey( SimpleForeignKey fk, XMLWriter out )
            throws XMLWriter.XMLException {
        XMLWriter fkStream;
        fkStream = out.addElement( "foreignKey" );
        fkStream.addElement( "fkName", fk.getName() );
        fkStream.addElement( "referenceTable", fk.getContainerRelationName() );
        fkStream.addElement( "referencedTable", fk.getReferencedAttribute().getContainerRelationName() );
        fkStream.addElement( "referencedColumn", fk.getReferencedAttribute().getName() );
    }

    public void serializeRelation( Relation rel, XMLWriter schemaWriter )
            throws XMLWriter.XMLException {
        XMLWriter rwriter = schemaWriter.addElement( "table" );
        rwriter.addElement( "table_name", rel.getName() );

        // attributes
        Attribute att;
        Vector<Attribute> atts = rel.getAttributes();
        for ( int i = 0; i < atts.size(); i++ ) {
            att = atts.elementAt( i );
            serializeAttribute( att, rwriter );
        }
    }

    public void serializeAttribute( Attribute att, XMLWriter tableWriter )
            throws XMLWriter.XMLException {
        XMLWriter awriter = tableWriter.addElement( "attribute" );
        awriter.addElement( "attribute_name", att.getName() );
        awriter.addElement( "attribute_type", att.getRdbValueType() );
    }

    public void serialize( PrintStream out ) throws IOException,
            XMLWriter.XMLException {
        serializeXML();
        _xmlStream.serialize( out );
    }

}